#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
#include <ranges>
#include <type_traits>
#include <utility>
#include <vector>

using i64 = int64_t;

template<class ...Args>
void input(Args&&...args){
    (std::cin>>...>>std::forward<Args>(args));
}

template<class ...Args>
void print(Args&&...args){
    ((std::cout<<args<<' '), ...);
    std::cout<<'\n';
}

template<class T>
std::remove_cvref_t<T> input(){
    std::remove_cvref_t<T> tmp;
    std::cin>>tmp;
    return tmp;
}

template<class _T>
struct SegTree{
    using T = std::remove_cvref_t<_T>;
    static_assert(std::is_integral_v<T>, "Please use number-like type");

    const i64 size;
    std::vector<T> tree;
    std::vector<T> lazy;

    SegTree(const std::vector<T> &arr):size(arr.size()), tree(arr.size()*4, T{}), lazy(arr.size()*4, T{}){
        init(arr, 0, arr.size()-1, 0);
    }

    void update(const i64 ul, const i64 ur, const i64 val){
        update(ul, ur, 0, size-1, 0, val);
    }

    [[nodiscard("Do not forget to use the result of query")]] T query(const i64 ql, const i64 qr){
        return query(ql, qr, 0, size-1, 0);
    }

private:
    void init(const std::vector<T> &arr, const i64 l, const i64 r, const i64 n){
        if(l==r){
            tree[n] = arr[l];
            return;
        }

        const i64 mid = (l+r)/2;

        init(arr, l, mid, n*2+1);
        init(arr, mid+1, r, n*2+2);

        tree[n] = tree[n*2+1] + tree[n*2+2];
    }

    T query(const i64 ql, const i64 qr, const i64 l, const i64 r, const i64 n){
        if(lazy[n]!=0){
            tree[n] += lazy[n] * (r-l+1);
            if(l!=r){
                lazy[n*2+1] += lazy[n];
                lazy[n*2+2] += lazy[n];
            }
            lazy[n]=0;
        }

        if(qr < l || r < ql){
            return 0;
        }
        
        if(ql<=l && r<=qr){
            return tree[n];
        }

        const i64 mid{(l+r)/2};

        T ret{};

        ret+=query(ql, qr, l, mid, n*2+1);
        ret+=query(ql, qr, mid+1, r, n*2+2);

        return ret;
    }

    void update(const i64 ul, const i64 ur, const i64 l, const i64 r, const i64 n, const T val){
        if(lazy[n]!=0){
            tree[n] += lazy[n] * (r-l+1);
            if(l!=r){
                lazy[n*2+1] += lazy[n];
                lazy[n*2+2] += lazy[n];
            }
            lazy[n]=0;
        }

        if(ur < l || r < ul){
            return;
        }

        if(ul <= l && r <= ur){
            tree[n] += (r-l+1)*val;
            if(l!=r){
                lazy[n*2+1] += val;
                lazy[n*2+2] += val;
            }
            return;
        }

        const i64 mid = (l+r)/2;

        update(ul, ur, l, mid, n*2+1, val);
        update(ul, ur, mid+1, r, n*2+2, val);
        tree[n] = tree[n*2+1] + tree[n*2+2];
    }
};

int main(){
    std::iostream::sync_with_stdio(false), std::cin.tie(nullptr), std::cout.tie(nullptr);

    const i64 n{input<decltype(n)>()}, m{input<decltype(m)>()};
    
    std::vector<i64> arr(n);
    std::for_each(arr.begin(), arr.end(), [](auto &i){
        input(i);
    });

    SegTree<i64> st(arr);

    std::ranges::for_each(std::ranges::views::iota(0,m), [&st](auto){
        const i64 k{input<decltype(k)>()};
        if(k==1){
            const i64 x{input<i64>()-1}, y{input<i64>()-1}, val{input<i64>()};
            st.update(x, y, val);
        }else{
            const i64 x{input<i64>()-1}, y{input<i64>()-1};
            print(st.query(x, y));
        }
    });
}